const Router = require("koa-router");
const logger = require("../utils/logger");
const runCmd = require("../utils/runCmd");
const fs = require("fs");

// 开启 socket 服务,创建一个空数组来存储socket连接列表
let socketList = [];
let socketIo = null;

// Git Bash 的路径（默认安装路径）
const bashCmd = "C:\\PROGRA~1\\Git\\bin\\bash.exe";
const isWin32 = process.platform === "win32" ? true : false;
const cmd = isWin32 ? bashCmd : "sh";

class RunShell {
  constructor(server) {
    // 将Socket.IO绑定到HTTP服务器上
    socketIo = require("socket.io")(server);
    this.router = new Router({ prefix: "/shell" });
  }

  init() {
    // 监听Socket.IO的连接事件
    socketIo.on("connection", (socket) => {
      // 当有新的客户端连接时，这里的代码会被执行
      socketList.push(socket);
      logger.info("a user connected");
    });

    this.router.post("/deploy", async (ctx) => {
      if (!ctx.session.isLogin) {
        ctx.body = {
          code: -2,
          msg: "未登录",
        };
        return;
      }

      // 执行部署脚本
      // koa 注意异步 404 的问题
      let execFunc = () => {
        return new Promise((resolve, reject) => {
          try {
            runCmd(
              cmd,
              ["./deploy-master.sh"],
              function (text) {
                resolve(text);
              },
              socketIo,
              "deploy-log"
            );
          } catch (e) {
            logger.info(e);
            reject(e);
          }
        });
      };

      try {
        let res = await execFunc();
        ctx.body = {
          code: 0,
          msg: res,
        };
      } catch (e) {
        ctx.body = {
          code: -1,
          msg: e.message,
        };
      }
    });

    this.router.post("/runShell", async (ctx) => {
      if (!ctx.session.isLogin) {
        ctx.body = {
          code: -2,
          msg: "未登录",
        };
        return;
      }

      let {
        shellText,
        shellName = "temp.sh",
        timeoutMinute = 2,
      } = ctx.request.body;
      const shellFilePath = process.cwd() + "/" + shellName;
      console.log("shellFilePath", shellFilePath);
      try {
        fs.writeFileSync(shellFilePath, shellText, {
          encoding: "utf-8",
        });
      } catch (e) {
        console.log("errr:", e);
        ctx.body = {
          code: -1,
          msg: e.message,
        };
      }

      // 执行部署脚本
      // koa 注意异步 404 的问题
      let execFunc = () => {
        return new Promise((resolve, reject) => {
          try {
            runCmd(
              cmd,
              [shellFilePath],
              function (text, isError) {
                isError ? reject(new Error(text)) : resolve(text);
              },
              socketIo,
              "runShell",
              timeoutMinute
            );
          } catch (e) {
            logger.info(e);
            reject(e);
          }
        });
      };

      try {
        let res = await execFunc();
        ctx.body = {
          code: 0,
          msg: res,
        };
      } catch (e) {
        ctx.body = {
          code: -1,
          msg: e.message,
        };
      }
    });

    this.router.get("/get", async (ctx) => {
      if (!ctx.session.isLogin) {
        ctx.body = {
          code: -2,
          msg: "未登录",
        };
        return;
      }

      const files = fs.readdirSync(`${process.cwd()}`);
      let result = [];
      // files [ 'args.json', 'temp.sh', 'test.sh' ]
      // 过滤排除文件
      let filesFilter = files.filter((item) => {
        if (
          ["args.json", "temp.sh", "micro-deploy.js", "start.js"].includes(item)
        ) {
          return false;
        }
        if (item.startsWith(".")) {
          return false;
        }
        return true;
      });
      console.log(filesFilter);

      filesFilter.forEach((filePath) => {
        console.log(`'${filePath}'`);
        let info = { name: filePath, content: "", desc: "" };
        try {
          const content = fs
            .readFileSync(`${process.cwd()}/${filePath}`)
            .toString();
          info.content = content;
          result.push(info);
        } catch (e) {
          console.log("非文件", e.message);
        }
      });

      // [
      //   { name: "1.sh", content: "ls\npwd\n", desc: "定时任务" },
      //   {
      //     name: "2.sh",
      //     content: "git pull;\n npm i && npm run build\n",
      //     desc: "项目部署",
      //   },
      // ],
      ctx.body = {
        code: 0,
        data: {
          processCwd: process.cwd(),
          shellList: result,
        },
        msg: "成功",
      };
    });

    this.router.post("/runCurShell", async (ctx) => {
      if (!ctx.session.isLogin) {
        ctx.body = {
          code: -2,
          msg: "未登录",
        };
        return;
      }

      let { name, timeoutMinute } = ctx.request.body;
      const shellFilePath = process.cwd() + "/" + name;
      console.log("cur shellFilePath", shellFilePath);

      // // 执行部署脚本
      // // koa 注意异步 404 的问题
      let execFunc = () => {
        return new Promise((resolve, reject) => {
          try {
            runCmd(
              cmd,
              [shellFilePath],
              function (text, isError) {
                isError ? reject(new Error(text)) : resolve(text);
              },
              socketIo,
              "shell-log-" + name,
              timeoutMinute
            );
          } catch (e) {
            logger.info(e);
            reject(e);
          }
        });
      };

      try {
        let res = await execFunc();
        ctx.body = {
          code: 0,
          msg: res,
        };
      } catch (e) {
        ctx.body = {
          code: -1,
          msg: e.message,
        };
      }
    });
  }
}

module.exports = RunShell;
